package pers.cj.pdos.controller;


import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.metadata.Sheet;
import com.alibaba.excel.support.ExcelTypeEnum;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import pers.cj.pdos.controller.base.BaseController;
import pers.cj.pdos.controller.entity.ResponseData;
import pers.cj.pdos.controller.entity.ResponseEntity;
import pers.cj.pdos.controller.entity.ResponseList;
import pers.cj.pdos.entity.*;
import pers.cj.pdos.excel.ExcelGoodsTransfer;
import pers.cj.pdos.service.IGoodsTransferService;
import pers.cj.pdos.service.IHouseInService;
import pers.cj.pdos.service.IHouseOutService;
import pers.cj.pdos.task.CleanTempExcelTask;
import pers.cj.pdos.utils.*;
import pers.cj.pdos.vo.*;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.util.*;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author chenj
 * @since 2019-11-04
 */
@Controller
@RequestMapping("/house")
public class GoodsTransferController extends BaseController {
    @Autowired
    IGoodsTransferService goodsTransferService;
    @Autowired
    IHouseOutService houseOutService;
    @Autowired
    IHouseInService houseInService;

    @RequestMapping("/goodsTransfer")
    @RequiresPermissions("goodsTransfer:query")
    public String goodsTemplate() {
        return "goodsTransfer/goodsTransfer";
    }


    @RequestMapping("/goodsTransferNew")
    @RequiresPermissions("goodsTransfer:insert")
    public String goodsPacketNew() {
        return "goodsTransfer/goodsTransferNew";
    }

    @RequestMapping("/goodsTransferDetail")
    @RequiresPermissions("goodsTransfer:query")
    public String goodsTransferDetail(Model model, String id) {
        model.addAttribute("id",id);
        return "goodsTransfer/goodsTransferDetail";
    }

    @ResponseBody
    @RequiresPermissions("goodsTransfer:query")
    @RequestMapping("/goodsTransfer/getList")
    public ResponseList getList(int page,
                                int limit,
                                String close,
                                String search,
                                String no,
                                String goodsName,
                                String remark,
                                String date1,
                                String date2,
                                String outStoreId,
                                String inStoreId,
                                String userId,
                                String makeTime1,
                                String makeTime2,
                                String outHouseId,
                                String inHouseId,
                                String makeUserId,
                                String outStatus,
                                String inStatus){
        Company company = getCompany();
        UserVo userVo = getLoginUserVo();

        List<GoodsTransferVo> list = goodsTransferService.listVo(company.getId(),
                page,
                limit,
                Utils.genBoolean(close),
                Utils.genLikeData(search),
                Utils.genLikeData(no),
                Utils.genLikeData(goodsName),
                Utils.genLikeData(remark),
                Utils.genDate(date1),
                Utils.genDate(date2),
                outStoreId,
                inStoreId,
                PdosUtils.getViewOrderStoreId(userVo,null),
                PdosUtils.getViewOrderUserId(userVo,userId),
                Utils.genDate(makeTime1),
                Utils.genDate(makeTime2),
                outHouseId,
                inHouseId,
                makeUserId,
                Utils.genInteger(outStatus),
                Utils.genInteger(inStatus));

        long count = goodsTransferService.count(company.getId(),
                Utils.genBoolean(close),
                Utils.genLikeData(search),
                Utils.genLikeData(no),
                Utils.genLikeData(goodsName),
                Utils.genLikeData(remark),
                Utils.genDate(date1),
                Utils.genDate(date2),
                outStoreId,
                inStoreId,
                PdosUtils.getViewOrderStoreId(userVo,null),
                PdosUtils.getViewOrderUserId(userVo,userId),
                Utils.genDate(makeTime1),
                Utils.genDate(makeTime2),
                outHouseId,
                inHouseId,
                makeUserId,
                Utils.genInteger(outStatus),
                Utils.genInteger(inStatus));

        return ResponseList.success(count,list);
    }

    @ResponseBody
    @RequiresPermissions("goodsTransfer:insert")
    @RequestMapping("/goodsTransfer/add")
    public ResponseEntity add(@RequestBody GoodsTransferVo goodsTransferVo){
        Company company = getCompany();
        BusinessSet businessSet = getBusinessSet();

        if (Utils.isEmpty(goodsTransferVo.getNo())){
            return ResponseEntity.fail("编号不能为空");
        }

        if (Utils.isEmpty(goodsTransferVo.getGoodsTransferGoodsVoList())){
            return ResponseEntity.fail("请选择商品");
        }


        if (Utils.isEmpty(goodsTransferVo.getOutHouseId())){
            return ResponseEntity.fail("请选择出库仓库");
        }

        if (Utils.isEmpty(goodsTransferVo.getInHouseId())){
            return ResponseEntity.fail("请选择入库仓库");
        }

        if (goodsTransferVo.getInHouseId().equals(goodsTransferVo.getOutHouseId())){
            return ResponseEntity.fail("出库仓库和入库仓库不能相同");
        }

        if (goodsTransferService.checkNo(goodsTransferVo.getNo(),company.getId())){
            return ResponseEntity.fail("编号已被使用");
        }

        if (getHouseLocking(goodsTransferVo.getInHouseId())) {
            return ResponseEntity.fail("入库仓库被锁定，请更换仓库");
        }

        if (getHouseLocking(goodsTransferVo.getOutHouseId())) {
            return ResponseEntity.fail("出库仓库被锁定，请更换仓库");
        }

        if (!PdosUtils.houseInOut(businessSet)) {
            //为启用出入库，检查其出库的库存
            GoodsUtil goodsUtil = new GoodsUtil(goodsTransferVo.getOutHouseId(),goodsTransferVo.getGoodsTransferGoodsVoList());
            String msg = goodsUtil.checkStock();
            if (msg!=null){
                return ResponseEntity.fail(msg);
            }
        }

        //准备插入数据库的数据
        GoodsTransfer goodsTransfer = DataUtil.genEntityFromVo(GoodsTransfer.class, goodsTransferVo);
        DataUtil.processEntity(company,goodsTransfer);
        if (!PdosUtils.houseInOut(businessSet)) {
            goodsTransfer.setOutStatus(3);
            goodsTransfer.setInStatus(3);
            goodsTransfer.setStatus(1);
        }else{
            goodsTransfer.setOutStatus(1);
            goodsTransfer.setInStatus(1);
            goodsTransfer.setStatus(2);
        }
        goodsTransfer.setMakeUserId(getLoginUserId());
        goodsTransfer.setMakeTime(goodsTransfer.getTime());
        goodsTransfer.setClose(false);

        List<GoodsTransferGoods> goodsTransferGoodsList = new ArrayList<>();
        List<GoodsSn> goodsSnList = new ArrayList<>();
        List<GoodsSnLog> goodsSnOutLogList = new ArrayList<>();
        List<GoodsSnLog> goodsSnInLogList = new ArrayList<>();

        for (GoodsTransferGoodsVo vo:goodsTransferVo.getGoodsTransferGoodsVoList()) {
            GoodsTransferGoods entity = DataUtil.genEntityFromVo(GoodsTransferGoods.class, vo);
            DataUtil.processEntity(company,entity);
            entity.setGoodsTransferId(goodsTransfer.getId());
            goodsTransferGoodsList.add(entity);

            if (!Utils.isEmpty(vo.getGoodsSnList())){
                for (GoodsSn goodsSn : vo.getGoodsSnList()) {
                    goodsSnList.add(goodsSn);
                    goodsSnOutLogList.add(genGoodsSnLog(company,9,goodsSn,entity));
                    goodsSnInLogList.add(genGoodsSnLog(company,8,goodsSn,entity));
                }
            }
        }

        goodsTransferService.insert(businessSet, goodsTransfer, goodsTransferGoodsList,goodsSnList,goodsSnOutLogList,goodsSnInLogList);

        if (!Utils.isEmpty(goodsSnList) && PdosUtils.houseInOut(businessSet)) {
            //已启用待出库入管理，但是前台传入了sn号，提示
            return ResponseEntity.success("处理成功，管理员在您新增单据过程中启用了出入库管理，录入的sn需要在出库时重新选择");
        }
        return ResponseEntity.success();
    }

    private GoodsSnLog genGoodsSnLog(Company company, int type, GoodsSn goodsSn, GoodsTransferGoods entity) {
        GoodsSnLog log = new GoodsSnLog();
        DataUtil.processEntity(company,log);
        log.setGoodsId(goodsSn.getGoodsId());
        log.setSn(goodsSn.getSn());
        log.setGoodsTransferGoodsId(entity.getId());
        log.setType(type);
        return log;
    }

    @ResponseBody
    @RequiresPermissions("goodsTransfer:close")
    @RequestMapping("/goodsTransfer/close")
    public ResponseEntity close(@RequestBody GoodsTransfer goodsTransfer){
        //检查是否已经关闭
        if (goodsTransferService.checkClose(goodsTransfer)){
            return ResponseEntity.fail("该单据已被关闭，不能重复关闭");
        }

        if(houseInService.checkByLinkId(goodsTransfer.getId())) {
            return ResponseEntity.fail("该订单存在入库单，请先作废对应的入库单");
        }


        if(houseOutService.checkByLinkId(goodsTransfer.getId())) {
            return ResponseEntity.fail("该订单存在出库单，请先作废对应的出库单");
        }

        try {
            goodsTransferService.close(goodsTransfer, getBusinessSet());
            return ResponseEntity.success();
        }catch (Exception e) {
            return ResponseEntity.fail("关闭订单失败");
        }
    }


    @ResponseBody
    @RequiresPermissions("goodsTransfer:insert")
    @RequestMapping("/goodsTransfer/updateImage")
    public ResponseEntity updateImage(@RequestBody GoodsTransfer goodsTransfer){
        try {
            GoodsTransfer temp = new GoodsTransfer();
            temp.setId(goodsTransfer.getId());
            temp.setImage(goodsTransfer.getImage());
            goodsTransferService.updateById(temp);
            return ResponseEntity.success();
        }catch (Exception e) {
            return ResponseEntity.fail("更新图片失败");
        }
    }


    @ResponseBody
    @RequestMapping(value = "/goodsTransfer/uploadImg", method = RequestMethod.POST)
    public ResponseData uploadImg(MultipartFile imageFile) {
        return processUploadImg(imageFile, "goodsTransfer");
    }

    @ResponseBody
    @RequestMapping("/goodsTransfer/getVoById.action")
    public ResponseData getVoById(String id){
        if (Utils.isEmpty(id)){
            return ResponseData.fail("id不能为空");
        }

        GoodsTransferVo goodsTransferVo = goodsTransferService.getVoById(id);
        if (goodsTransferVo == null) {
            return ResponseData.fail("id不正确");
        }
        return ResponseData.success(goodsTransferVo);
    }


    @ResponseBody
    @RequiresPermissions("goodsTransfer:export")
    @RequestMapping("/goodsTransfer/export")
    public ResponseData export(String close,
                               String search,
                               String no,
                               String goodsName,
                               String remark,
                               String date1,
                               String date2,
                               String outStoreId,
                               String inStoreId,
                               String userId,
                               String makeTime1,
                               String makeTime2,
                               String outHouseId,
                               String inHouseId,
                               String makeUserId,
                               String outStatus,
                               String inStatus){
        Company company = getCompany();
        UserVo userVo = getLoginUserVo();

        List<GoodsTransferVo> list = goodsTransferService.listVo(company.getId(),
                null,
                null,
                Utils.genBoolean(close),
                Utils.genLikeData(search),
                Utils.genLikeData(no),
                Utils.genLikeData(goodsName),
                Utils.genLikeData(remark),
                Utils.genDate(date1),
                Utils.genDate(date2),
                outStoreId,
                inStoreId,
                PdosUtils.getViewOrderStoreId(userVo,null),
                PdosUtils.getViewOrderUserId(userVo,userId),
                Utils.genDate(makeTime1),
                Utils.genDate(makeTime2),
                outHouseId,
                inHouseId,
                makeUserId,
                Utils.genInteger(outStatus),
                Utils.genInteger(inStatus));

        String fileName = "调拨单列表" + DateUtils.getDate(new Date(), DateUtils.YYYYMMDDHHMMSSSS) + ".xlsx";
        try {
            String path = FileProperUtil.getInstance().getVal("excel.temp");
            OutputStream out = new FileOutputStream(path+fileName);
            ExcelWriter writer = new ExcelWriter(out, ExcelTypeEnum.XLSX,true);
            Sheet sheet1 = new Sheet(1,0, ExcelGoodsTransfer.class);
            sheet1.setSheetName("调拨单信息");
            writer.write(genExcelList(list), sheet1);
            writer.finish();
            out.close();
            CleanTempExcelTask.put(fileName,new Date().getTime());
            return ResponseData.success(fileName);
        } catch (IOException e) {
            return ResponseData.fail("订单列表导出失败");
        }
    }

    private List<ExcelGoodsTransfer> genExcelList(List<GoodsTransferVo> goodsTransferVoList) {
        BusinessSet businessSet = getBusinessSet();
        List<ExcelGoodsTransfer> list = new ArrayList<>();
        for (GoodsTransferVo vo : goodsTransferVoList){
            ExcelGoodsTransfer excel = new ExcelGoodsTransfer();
            excel.setDate(DateUtils.getDate(vo.getDate(), DateUtils.YYYY_MM_DD));
            excel.setNo(vo.getNo());
            excel.setOutStore(vo.getOutHouseVo().getStore().getName());
            excel.setOutHouse(vo.getOutHouseVo().getName());
            String status = "";
            if(vo.getOutStatus() == 1) {
                status = "待出库";
            } else if(vo.getOutStatus() == 2) {
                status = "部分出库";
            } else {
                status = "已出库";
            }
            excel.setOutStatus(status);
            String goods = "";
            BigDecimal number = new BigDecimal(0);
            for (GoodsTransferGoodsVo goodsTransferGoodsVo : vo.getGoodsTransferGoodsVoList()){
                number = number.add(goodsTransferGoodsVo.getNumber());
                goods += goodsTransferGoodsVo.getGoodsVo().getName() + "、";
            }
            goods = goods.substring(0,goods.length()-1);
            excel.setGoods(goods);
            excel.setNumber(PdosUtils.getNumber(number,getBusinessSet()));

            excel.setInStore(vo.getInHouseVo().getStore().getName());
            excel.setInHouse(vo.getInHouseVo().getName());
            if(vo.getOutStatus() == 1) {
                status = "待入库";
            } else if(vo.getOutStatus() == 2) {
                status = "部分入库";
            } else {
                status = "已入库";
            }
            excel.setOutStatus(status);
            excel.setUser(vo.getUser().getName());
            excel.setMakeUser(vo.getMakeUser().getName());
            excel.setOtherAmt(PdosUtils.getPrice(vo.getOtherAmt(),businessSet));
            excel.setSettAccount(vo.getSettAccountVo().getStore().getName() + ">" + vo.getSettAccountVo().getName());
            excel.setRemark(vo.getRemark());
            excel.setClose(vo.getClose() ? "是":"否");
            list.add(excel);
        }
        return list;
    }
}
